{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f40a9456",
   "metadata": {},
   "source": [
    "# 多重继承"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "86d9ccb1",
   "metadata": {},
   "source": [
    "多重继承指的是一个类可以同时从多个父类继承行为与特征的功能。Python 支持多重继承的。\n",
    "\n",
    "例如，可以将之前的Leaf类进行抽象，树叶Leaf类，父类："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e0c998bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Leaf(object):\n",
    "    def __init__(self, color='green'):\n",
    "        self.color = color"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0fc49c8f",
   "metadata": {},
   "source": [
    "ColorChangingLeaf类，颜色可变的树叶，继承Leaf类："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "1213971e",
   "metadata": {},
   "outputs": [],
   "source": [
    "class ColorChangingLeaf(Leaf):\n",
    "    def change(self, new_color='brown'):\n",
    "        self.color = new_color"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "57e4c923",
   "metadata": {},
   "source": [
    "DeciduousLeaf类，落叶类植物的树叶，继承Leaf类："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "254d5547",
   "metadata": {},
   "outputs": [],
   "source": [
    "class DeciduousLeaf(Leaf):\n",
    "    def fall(self):\n",
    "        print(\"A leaf is falling!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82908e7f",
   "metadata": {},
   "source": [
    "MapleLeaf类，枫叶，枫叶颜色可变，同时枫树是落叶类植物，可以让它同时继承ColorChangingLeaf类和DeciduousLeaf类。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "15827727",
   "metadata": {},
   "outputs": [],
   "source": [
    "class MapleLeaf(ColorChangingLeaf, DeciduousLeaf):\n",
    "    pass"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "e683fc72",
   "metadata": {},
   "source": [
    "多重继承在定义时，只需要用逗号将多个父类隔开。MapleLeaf类只是简单的继承了两个类型。MapleLeaf类的对象可以使用两个父类的方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "172135c2",
   "metadata": {},
   "outputs": [],
   "source": [
    "mleaf = MapleLeaf()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "2a8e93a0",
   "metadata": {},
   "source": [
    "例如，从Leaf类继承而来的属性："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "bf1d7dd9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'green'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mleaf.color"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "0a5b9445",
   "metadata": {},
   "source": [
    "从ColorChangingLeaf类继承而来的方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "aebceb2b",
   "metadata": {},
   "outputs": [],
   "source": [
    "mleaf.change(\"red\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "7220d3b3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'red'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mleaf.color"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "5325fa69",
   "metadata": {},
   "source": [
    "从DeciduousLeaf类继承而来方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c597ff5e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A leaf is falling!\n"
     ]
    }
   ],
   "source": [
    "mleaf.fall()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aded6105",
   "metadata": {},
   "source": [
    "## 继承顺序"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "18322688",
   "metadata": {},
   "source": [
    "有时候多个父类可能会发生冲突。例如，可以在ColorChangingLeaf的定义中增加一个`.fall()`方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "4bdc6d5a",
   "metadata": {},
   "outputs": [],
   "source": [
    "class ColorChangingLeaf(Leaf):\n",
    "    def change(self, new_color='brown'):\n",
    "        self.color = new_color\n",
    "        \n",
    "    def fall(self):\n",
    "        print(\"I am falling!!!!\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "1fd50db3",
   "metadata": {},
   "source": [
    "在两个父类的`.fall()`方法不同时，Python会优先使用定义在前的父类的方法。\n",
    "\n",
    "当ColorChangingLeaf类在前时，使用的是ColorChangingLeaf类的方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "6d332069",
   "metadata": {},
   "outputs": [],
   "source": [
    "class MapleLeaf(ColorChangingLeaf, DeciduousLeaf):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "f6bd05d1",
   "metadata": {},
   "outputs": [],
   "source": [
    "mleaf = MapleLeaf()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "c283c608",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I am falling!!!!\n"
     ]
    }
   ],
   "source": [
    "mleaf.fall()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "46a760be",
   "metadata": {},
   "source": [
    "反过来定义时，使用的是DeciduousLeaf类的方法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "62525002",
   "metadata": {},
   "outputs": [],
   "source": [
    "class MapleLeaf(DeciduousLeaf, ColorChangingLeaf):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c8fccc73",
   "metadata": {},
   "outputs": [],
   "source": [
    "mleaf = MapleLeaf()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "ad1aa5ff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A leaf is falling!\n"
     ]
    }
   ],
   "source": [
    "mleaf.fall()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "3592cac1",
   "metadata": {},
   "source": [
    "继承的顺序可以通过该类的`.__mro__`属性或mro()方法来查看："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "39201c5e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(__main__.MapleLeaf,\n",
       " __main__.DeciduousLeaf,\n",
       " __main__.ColorChangingLeaf,\n",
       " __main__.Leaf,\n",
       " object)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "MapleLeaf.__mro__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "c13c5538",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[__main__.MapleLeaf,\n",
       " __main__.DeciduousLeaf,\n",
       " __main__.ColorChangingLeaf,\n",
       " __main__.Leaf,\n",
       " object]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "MapleLeaf.mro()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c5be1ab",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
